import { Directive, Input, ElementRef, OnInit, AfterViewInit } from '@angular/core';
import { Observable, fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

// 图片懒加载
@Directive({
    selector: '[imgLazyLoad]'
})
export class ImgLazyLoadDirective implements OnInit, AfterViewInit {
    @Input() imgLazyLoad;       // 需要加载的图片路径
    @Input() imageBeforeLoad;   // 加载之前显示的图片的路径
    @Input() selector;          // 滚动页面的selector
    @Input() imageLazyDistanceFromBottomToLoad;  // 距离底部多少距离是开始加载
    @Input() imageLazyDistanceFromRightToLoad;   // 距离右边部多少距离是开始加载

    img = new Image();
    hasLoad = false;
    observer = null;

    constructor(public el: ElementRef) {
    }

    ngOnInit() {
        if (!this.imageLazyDistanceFromBottomToLoad) {
            this.imageLazyDistanceFromBottomToLoad = 0;
        }
        if (!this.imageLazyDistanceFromRightToLoad) {
            this.imageLazyDistanceFromRightToLoad = 0;
        }
        if (this.imageBeforeLoad) {
            this.el.nativeElement.src = this.imageBeforeLoad;
        }
    }

    ngAfterViewInit() {
        if (this.isInView()) {
            this.loadImage();
        }
        const scrollContent = document.getElementsByTagName(this.selector)[0].getElementsByClassName('scroll-content')[0]
        || document.getElementsByTagName(this.selector)[0];
        this.observer = fromEvent(scrollContent, 'scroll')
        .pipe(debounceTime(50))  // .debounceTime(50)
        // .throttle(ev => Observable.interval(50))
        .subscribe((event) => {
            // console.log(event);
            if (this.isInView() && !this.hasLoad) {
                this.loadImage();
            }
        });

    }

    isInView() {
        const clientHeight = document.documentElement.clientHeight;
        const clientWidth = document.documentElement.clientWidth;
        const imageRect = this.el.nativeElement.getBoundingClientRect();
        return (imageRect.top >= 0 && imageRect.top <= clientHeight + parseInt(this.imageLazyDistanceFromBottomToLoad, 10))
              && (imageRect.left >= 0 && imageRect.left <= clientWidth + parseInt(this.imageLazyDistanceFromRightToLoad, 10));
    }

    loadImage() {
        this.img.src = this.imgLazyLoad;
        console.log('time1', new Date().getTime());
        this.img.onload = () => {
            console.log('time2', new Date().getTime());
            this.hasLoad = true;
            this.el.nativeElement.src = this.imgLazyLoad;
        };
    }
}
